package cn.com.main;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 比较class属性是否一致性
 *
 * @author LiuGuodong
 * @date 2024/02/20
 */
public class compareAttributesForConsistency {
    public static void main(String[] args) {
        // 两个类的示例
        Class<?> class1 = MyClass1.class;
        Class<?> class2 = MyClass2.class;

        // 获取类的所有属性
        Field[] fields1 = class1.getDeclaredFields();
        Field[] fields2 = class2.getDeclaredFields();

        // 对比属性名称
        List<String> strings = compareFields(getCollect(fields1), getCollect(fields2));
        List<Field> isSame = compareFields(fields1, fields2);

        if (isSame.isEmpty() || strings.isEmpty()) {
            strings.forEach(System.out::println);
            System.out.println("两个类的属性名称相同。");
        } else {
            strings.forEach(System.out::println);
            System.out.println("两个类的属性名称不同。");
        }
    }

    @NotNull
    private static Set<String> getCollect(Field[] fields1) {
        return Arrays.stream(fields1).map(Field::getName).collect(Collectors.toSet());
    }

    private static List<String> compareFields(Set<String> fields1, Set<String> fields2) {
        List<String> collect = fields2.stream().filter(e -> !fields1.contains(e)).collect(Collectors.toList());
        List<String> collect1 = fields1.stream().filter(e -> !fields2.contains(e)).collect(Collectors.toList());
        return Stream.concat(collect1.stream(), collect.stream()).distinct().collect(Collectors.toList());
    }


    private static List<Field> compareFields(Field[] fields1, Field[] fields2) {
        Set<Field> result = new HashSet<>();

        for (Field field1 : fields1) {
            for (Field field2 : fields2) {
                if (!field1.getName().equals(field2.getName())) {
                    result.add(field1);
                }
            }
        }

        return new ArrayList<>(result);
    }

    // 示例类1
    static class MyClass1 {
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("name")
        private String name;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("description")
        private String description;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("engine")
        private String engine;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("engine_version")
        private String engineVersion;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("specification")
        private String specification;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("storage_space")
        private Integer storageSpace;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("partition_num")
        private String partitionNum;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("used_storage_space")
        private Integer usedStorageSpace;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("connect_address")
        private String connectAddress;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("port")
        private Integer port;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("status")
        private String status;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("instance_id")
        private String instanceId;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("resource_spec_code")
        private String resourceSpecCode;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("charging_mode")
        private Integer chargingMode;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("vpc_id")
        private String vpcId;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("vpc_name")
        private String vpcName;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("created_at")
        private String createdAt;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("user_id")
        private String userId;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("user_name")
        private String userName;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("order_id")
        private String orderId;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("maintain_begin")
        private String maintainBegin;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("maintain_end")
        private String maintainEnd;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("enable_publicip")
        private Boolean enablePublicip;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("management_connect_address")
        private String managementConnectAddress;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("ssl_enable")
        private Boolean sslEnable;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("enterprise_project_id")
        private String enterpriseProjectId;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("is_logical_volume")
        private Boolean isLogicalVolume;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("extend_times")
        private Integer extendTimes;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("enable_auto_topic")
        private Boolean enableAutoTopic;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("type")
        private String type;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("product_id")
        private String productId;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("security_group_id")
        private String securityGroupId;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("security_group_name")
        private String securityGroupName;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("subnet_id")
        private String subnetId;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("subnet_name")
        private String subnetName;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("subnet_cidr")
        private String subnetCidr;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("available_zones")
        private List<String> availableZones = null;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("total_storage_space")
        private Integer totalStorageSpace;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("public_connect_address")
        private String publicConnectAddress;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("storage_resource_id")
        private String storageResourceId;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("storage_spec_code")
        private String storageSpecCode;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("service_type")
        private String serviceType;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("storage_type")
        private String storageType;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("retention_policy")
        private String retentionPolicy;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("kafka_public_status")
        private String kafkaPublicStatus;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("public_bandwidth")
        private Integer publicBandwidth;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("kafka_manager_user")
        private String kafkaManagerUser;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("enable_log_collection")
        private Boolean enableLogCollection;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("cross_vpc_info")
        private String crossVpcInfo;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("ipv6_enable")
        private Boolean ipv6Enable;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("ipv6_connect_addresses")
        private List<String> ipv6ConnectAddresses = null;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("connector_enable")
        private Boolean connectorEnable;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("connector_id")
        private String connectorId;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("mqs_connector_enable")
        private Boolean mqsConnectorEnable;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("mqs_connector_address")
        private String mqsConnectorAddress;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("plugin_enable")
        private Boolean pluginEnable;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("rest_enable")
        private Boolean restEnable;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("rest_connect_address")
        private String restConnectAddress;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("message_query_inst_enable")
        private Boolean messageQueryInstEnable;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("vpc_client_plain")
        private Boolean vpcClientPlain;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("support_features")
        private String supportFeatures;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("trace_enable")
        private Boolean traceEnable;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("pod_connect_address")
        private String podConnectAddress;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("disk_encrypted")
        private Boolean diskEncrypted;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("kafka_private_connect_address")
        private String kafkaPrivateConnectAddress;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("ces_version")
        private String cesVersion;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("node_num")
        private Integer nodeNum;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("publicip_address")
        private String publicipAddress;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("listeners")
        private Object listeners;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("public_access_enabled")
        private String publicAccessEnabled;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("public_boundwidth")
        private Integer publicBoundwidth;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("access_user")
        private String accessUser;
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonProperty("agent_enable")
        private Boolean agentEnable;
    }

    // 示例类2
    static class MyClass2 {
        /**
         * 底层资源ID
         */
        private String uuid;

        /**
         * 实例ID
         */
        private String instanceId;

        /**
         * 实例名称
         */
        private String name;

        /**
         * 引擎类型
         */
        private String engine;

        /**
         * 实例端口
         */
        private Integer port;

        /**
         * 实例状态
         */
        private String status;

        /**
         * 实例描述
         */
        private String description;

        /**
         * 实例类型
         */
        private String type;

        /**
         * 实例规格
         */
        private String specification;

        /**
         * 引擎版本
         */
        private String engineVersion;

        /**
         * 连接地址
         */
        private String connectAddress;


        /**
         * 资源规格代码
         */
        private String resourceSpecCode;

        /**
         * 计费模式
         */
        private Integer chargingMode;

        /**
         * VPC ID
         */
        private String vpcId;

        /**
         * VPC 名称
         */
        private String vpcName;

        /**
         * 创建时间
         */
        private Date createdAt;

        /**
         * 产品ID
         */
        private String productId;

        /**
         * 安全组ID
         */
        private String securityGroupId;

        /**
         * 安全组名称
         */
        private String securityGroupName;

        /**
         * 子网ID
         */
        private String subnetId;

        /**
         * 创实例使用的可用区列表
         */
        private String availableZones;

        /**
         * 用户ID
         */
        private String userId;

        /**
         * 用户名称
         */
        private String userName;

        /**
         * 访问用户
         */
        private String accessUser;

        /**
         * 运维开始时间
         */
        private Date maintainBegin;

        /**
         * 运维结束时间
         */
        private Date maintainEnd;

        /**
         * 是否启用日志收集
         */
        private boolean enableLogCollection;

        /**
         * 存储空间
         */
        private Integer storageSpace;

        /**
         * 总存储空间
         */
        private Integer totalStorageSpace;

        /**
         * 已使用存储空间
         */
        private Integer usedStorageSpace;

        /**
         * 分区数
         */
        private String partitionNum;

        /**
         * 是否启用公网IP
         */
        private boolean enablePublicip;

        /**
         * 是否启用SSL
         */
        private boolean sslEnable;

        /**
         * 跨VPC信息
         */
        private String crossVpcInfo;

        /**
         * 存储资源ID
         */
        private String storageResourceId;

        /**
         * 存储规格代码
         */
        private String storageSpecCode;

        /**
         * 服务类型
         */
        private String serviceType;

        /**
         * 存储类型
         */
        private String storageType;

        /**
         * 是否为逻辑卷
         */
        private boolean isLogicalVolume;

        /**
         * 扩展次数
         */
        private Integer extendTimes;

        /**
         * 保留策略
         */
        private String retentionPolicy;

        /**
         * 是否启用IPv6
         */
        private boolean ipv6Enable;

        /**
         * IPv6连接地址列表
         */
        private String ipv6ConnectAddresses;

        /**
         * 是否启用连接器
         */
        private boolean connectorEnable;

        /**
         * 是否启用MQS连接器
         */
        private boolean mqsConnectorEnable;

        /**
         * MQS连接器地址
         */
        private String mqsConnectorAddress;

        /**
         * 连接器ID
         */
        private String connectorId;

        /**
         * 是否启用REST
         */
        private boolean restEnable;

        /**
         * REST连接地址
         */
        private String restConnectAddress;

        /**
         * Kafka公网状态
         */
        private String kafkaPublicStatus;

        /**
         * 公网带宽
         */
        private Integer publicBandwidth;

        /**
         * 公网绑定带宽
         */
        private Integer publicBoundwidth;

        /**
         * 消息查询实例是否启用
         */
        private boolean messageQueryInstEnable;

        /**
         * VPC客户端明文
         */
        private boolean vpcClientPlain;

        /**
         * 支持的特性列表
         */
        private String supportFeatures;

        /**
         * 是否启用追踪
         */
        private boolean traceEnable;

        /**
         * 是否启用代理
         */
        private boolean agentEnable;

        /**
         * POD连接地址
         */
        private String podConnectAddress;

        /**
         * 是否磁盘加密
         */
        private boolean diskEncrypted;

        /**
         * Kafka私网连接地址
         */
        private String kafkaPrivateConnectAddress;

        /**
         * 是否启用自动主题
         */
        private boolean enableAutoTopic;

        /**
         * CES版本
         */
        private String cesVersion;

        /**
         * 是否启用插件
         */
        private boolean pluginEnable;

        /**
         * 公网访问是否启用
         */
        private String publicAccessEnabled;

        /**
         * 节点数量
         */
        private Integer nodeNum;
    }
}
